package bat.ke.qq.com.aspect;

import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;

/**
 * 定义切面
 */
@Aspect // 切面：包含切入点和通知
@Component
@Slf4j
public class AspectConfig {

    /**
     * 定义切入点
     */
    @Pointcut("execution(* bat.ke.qq.com.dao.*.*(..))")
    //@Pointcut("within(bat.ke.qq.com.dao.*)") //类
    //@Pointcut("args(String)")
    //@Pointcut("this(bat.ke.qq.com.dao.IFoxDao)")   // jdk动态代理 extend Proxy implements IFoxDao
    //@Pointcut("target(bat.ke.qq.com.dao.FoxDao)")
    //@Pointcut("args(String) || args()")
    //@Pointcut("execution(* bat.ke.qq.com.dao.*.*(String))")
    //@Pointcut("@annotation(bat.ke.qq.com.anno.Yuanma)")  //@Transational
    //@Pointcut("@target(bat.ke.qq.com.anno.Dao)")  // 目标是注解配置
    //@Pointcut("@within(bat.ke.qq.com.anno.Dao)")
    //@Pointcut("@args(bat.ke.qq.com.anno.Dao)") //传参类型配置@Dao的类型
    //@Pointcut("bean(foxDao)")
    private void pointcut() {

    }

    @Before("pointcut()")
    public void before(JoinPoint point) {
        point.getThis();
        log.info("before Advice");
    }

    @After("pointcut()")
    public void after() {
        log.info("After (finally) advice");
    }

    @AfterReturning("pointcut()")
    public void afterReturning() {
        log.info("after Returning Advice");
    }

    @AfterThrowing("pointcut()")
    public void afterThrowing() {
        log.info("after Throwing Advice");
    }

    @Around("pointcut()")
    public Object around(ProceedingJoinPoint point) throws Throwable {
        log.info("start around Advice");
        Object[] args = point.getArgs();
        for (int i = 0; i < args.length; i++) {
            log.info("====args: {}", args[i]);
            if (args[i].getClass().equals(String.class)) {
                args[i] += "xxx";
            }
        }
        // before
        Object result = point.proceed(args);
        // 处理逻辑
        log.info("end around Advice");
        return result;
    }


}
